package com.urbanski.clipboard.client.action;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import com.urbanski.clipboard.client.ClipboardClient;
import com.urbanski.clipboard.client.ServerConnection;
import com.urbanski.clipboard.client.util.ClientConstants.ClientCommand;
import com.urbanski.clipboard.common.message.CreateMessage;
import com.urbanski.clipboard.common.message.JoinMessage;
import com.urbanski.clipboard.common.message.Response;
import com.urbanski.util.logging.LoggingUtil;

public class ConnectActionHandler extends ClientActionHandler
{
	private static final Logger LOGGER = Logger.getLogger(ConnectActionHandler.class);

	private String host;
	private int port;
	private String alias;
	private List<Join> join = new ArrayList<>();
	private List<Create> create = new ArrayList<>();

	public ConnectActionHandler(String[] tokens)
	{
		super(ClientCommand.CONNECT, tokens);
	}

	@Override
	public void execute()
	{
		processArgs();
		if (host != null && port > 0)
		{
			ServerConnection serverConnection = ClipboardClient.addConnection(host, port, alias);
			LoggingUtil.logAndPrintInfo(LOGGER, "Successfully connected to " + host + ':' + port);
			for (Join j : join)
			{
				JoinMessage jm = new JoinMessage(j.session, j.password);
				try
				{
					LoggingUtil.logAndPrintInfo(LOGGER, "Attemping to join session " + j.session);
					serverConnection.sendMessage(jm);
					LoggingUtil.logAndPrintInfo(LOGGER, "Successfully joined " + j.session);
				}
				catch (IOException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			for (Create c : create)
			{
				CreateMessage cm = new CreateMessage(c.session, c.password, c.adminPassword);
				try
				{
					LoggingUtil.logAndPrintInfo(LOGGER, "Attemping to create session " + c.session);
					Response response = serverConnection.sendMessage(cm);
					LoggingUtil.logAndPrintInfo(LOGGER, response.getResponseText());
				}
				catch (IOException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			// TODO send joins and creates
		}
	}

	private void processArgs()
	{
		if (tokens.length < 3)
		{
			LoggingUtil.logAndPrintError(LOGGER, "Invalid number of arguments for connect command");
			return;
		}

		host = tokens[1];

		try
		{
			port = Integer.parseInt(tokens[2]);
		}
		catch (NumberFormatException e)
		{
			LoggingUtil.logAndPrintError(LOGGER, "Invalid port: " + tokens[2]);
			return;
		}

		for (int i = 3; i < tokens.length; i++)
		{
			if (tokens[i].equals("-a"))
			{
				if (i < tokens.length - 1)
				{
					alias = tokens[i + 1];
					i++;
				}
				else
				{
					System.err.println("Invalid alias option - no alias will be used");
					return;
				}
			}
			else if (tokens[i].equals("-j"))
			{
				Join j = new Join();
				if (i < tokens.length - 1)
				{
					j.session = tokens[i + 1];
					i++;

					// Get next token to see if it's a session password
					if (i < tokens.length - 1 && !tokens[i + 1].equals("-c") && !tokens[i + 1].equals("-j"))
					{
						j.password = tokens[i + 1];
						i++;
					}

					join.add(j);
				}
				else
				{
					System.err.println("Invalid join option - missing session name");
					return;
				}
			}
			else if (tokens[i].equals("-c"))
			{
				Create c = new Create();
				if (i < tokens.length - 2)
				{
					c.session = tokens[i + 1];
					c.adminPassword = tokens[i + 2];
					i += 2;

					// Get next token to see if it's a session password
					if (i < tokens.length - 1 && !tokens[i + 1].equals("-c") && !tokens[i + 1].equals("-j"))
					{
						c.password = tokens[i + 1];
						i++;
					}

					create.add(c);
				}
				else
				{
					System.err.println("Invalid create - missing session name or admin password");
					return;
				}
			}
		}
	}

	static class Join
	{
		private String session;
		private String password;

		String getCommand()
		{
			StringBuilder command = new StringBuilder("join ").append(session);
			if (password != null)
			{
				command.append(' ').append(password);
			}
			return command.toString();
		}
	}

	static class Create
	{
		private String session;
		private String adminPassword;
		private String password;

		String getCommand()
		{
			StringBuilder command = new StringBuilder("join ").append(session).append(' ').append(adminPassword);
			if (password != null)
			{
				command.append(' ').append(password);
			}
			return command.toString();
		}
	}

}
